﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;


namespace PrisonStep
{
    public class Spit
    {
        #region MemberVariables

        /// <summary>
        /// Will be used to represent different 
        /// </summary>
        public class SpitObject
        {
            public Matrix mOrientation;
            public float mSpeed;
        }

        private List<SpitObject> mSpitObjects = new List<SpitObject>();

        Model mModel;

        PrisonGame mGame;

        #endregion


        #region Properties

        public float SlimeWeight { get; set; }

        #endregion

        /// <summary>
        /// Constructor
        /// </summary>
        public Spit(PrisonGame aGame)
        {
            this.mGame = aGame;
        }

        public void LoadContent(ContentManager aContent)
        {
            mModel = aContent.Load<Model>("spit");
        }

        public void Update(GameTime aGameTime)
        {
            for (int i = 0; i < mSpitObjects.Count; i++)
            {
                Matrix lNewOrientation = mSpitObjects[i].mOrientation;
                lNewOrientation.Translation += lNewOrientation.Backward * mSpitObjects[i].mSpeed * (float)aGameTime.ElapsedGameTime.TotalSeconds;

                Vector3 lNormal = Vector3.Zero;
                string lRegion = mGame.TestRegion(lNewOrientation.Translation, ref lNormal);
                //Include the logic for the collisions of the 

                bool lCollision = TestForCollision(lRegion, lNewOrientation);
                if (!lCollision)
                {
                    mSpitObjects.Remove(mSpitObjects[i]);
                    i--;
                }
                else
                    mSpitObjects[i].mOrientation = lNewOrientation;


            }
        }

        public void Draw(GraphicsDeviceManager aGraphics, GameTime aGameTime)
        {
            aGraphics.GraphicsDevice.BlendState = BlendState.AlphaBlend;
            aGraphics.GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
            foreach (SpitObject lObject in mSpitObjects)
            {
                DrawModel(aGraphics, mModel, lObject.mOrientation);
                DrawModel(aGraphics, mModel, Matrix.CreateRotationX((float)Math.PI/2) * lObject.mOrientation );
            }
            aGraphics.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            aGraphics.GraphicsDevice.BlendState = BlendState.Opaque;

            
        }

        public void DrawModel(GraphicsDeviceManager aGraphics, Model aModel, Matrix aWorld)
        {
            foreach (ModelMesh lMesh in aModel.Meshes)
            {
                foreach (Effect lEffect in lMesh.Effects)
                {

                    if (lEffect is BasicEffect)
                    {
                        BasicEffect lBasicEffect = lEffect as BasicEffect;
                        lBasicEffect.EnableDefaultLighting();
                        lBasicEffect.World = aWorld;
                        lBasicEffect.View = mGame.Camera.View;
                        lBasicEffect.Projection = mGame.Camera.Projection;

                    }
                    else
                    {
                        lEffect.Parameters["World"].SetValue(aWorld);
                        lEffect.Parameters["View"].SetValue(mGame.Camera.View);
                        lEffect.Parameters["Projection"].SetValue(mGame.Camera.Projection);
                        lEffect.Parameters["Weight"].SetValue(SlimeWeight);
                    }

                }
                lMesh.Draw();
            }
        }

        /// <summary>
        /// The function to call if you want to fire a new spit object
        /// </summary>
        /// <param name="aOrientation"></param>
        public void AddSpit(Matrix aOrientation)
        {
            SpitObject lSpitObject = new SpitObject();
            lSpitObject.mOrientation = aOrientation;
            lSpitObject.mSpeed = 100;
            mSpitObjects.Add(lSpitObject);
        }

        private bool TestForCollision(string aRegion, Matrix aTransform)
        {
            bool lTemp = false;

            //Stops if it hits a shut door
            if (aRegion.StartsWith("R_Door"))
            {
                foreach (PrisonModel lModel in mGame.Models)
                {
                    int lSection = (int)Char.GetNumericValue(aRegion[aRegion.Length - 1]);
                    bool lTemp2 = lModel.CheckForOpenDoors(lSection, aTransform);

                    lTemp = lTemp || lTemp2;
                }
            }
            else
                lTemp = true;

            if (aRegion != "")
            {
                BoundingSphere lBS = new BoundingSphere(aTransform.Translation, 12.5f);
                if (mGame.Victoria.BoundingCyl.Intersect(lBS))
                {
                    mGame.Slimed = true;
                    mGame.Score -= 100;
                    lTemp = false;
                }
            }
            else if (aRegion.StartsWith("W_") || aRegion == "")
                lTemp = false ;



            return lTemp;
        }

    }
}
